import com.softwarecraftsmen.orogeny.BaseDirectory;
import com.softwarecraftsmen.orogeny.BuildScript;
import com.softwarecraftsmen.orogeny.UpperCaseEnvironmentVariableOnWindows;
import com.softwarecraftsmen.orogeny.filing.*;

import static com.softwarecraftsmen.archivers.zip.ZipArchiver.ZipArchive;
import static com.softwarecraftsmen.orogeny.actions.ArchiveAction.archiveAs;
import static com.softwarecraftsmen.orogeny.actions.ClassExistsAction.classExists;
import static com.softwarecraftsmen.orogeny.actions.CompileAction.compile;
import static com.softwarecraftsmen.orogeny.actions.CopyFilesAction.flatHardLinkFiles;
import static com.softwarecraftsmen.orogeny.actions.CopyFilesAction.hardLinkFiles;
import static com.softwarecraftsmen.orogeny.actions.ExecuteAction.FifteenSeconds;
import static com.softwarecraftsmen.orogeny.actions.ExecuteAction.execute;
import static com.softwarecraftsmen.orogeny.actions.JarTogetherAction.jarTogether;
import static com.softwarecraftsmen.orogeny.actions.MakeDirectoryAction.makeDirectory;
import static com.softwarecraftsmen.orogeny.actions.ManifestAction.manifest;
import static com.softwarecraftsmen.orogeny.actions.ModuleAction.module;
import static com.softwarecraftsmen.orogeny.actions.RegisterAction.register;
import static com.softwarecraftsmen.orogeny.actions.SignJarsAction.signJars;
import static com.softwarecraftsmen.orogeny.actions.TouchAction.touch;
import static com.softwarecraftsmen.orogeny.actions.execute.OperatingSystemAndPathDependentExecutable.operatingSystemAndPathDependentExecutable;
import static com.softwarecraftsmen.orogeny.actions.keys.ConvenientKey.key;
import static com.softwarecraftsmen.orogeny.actions.keys.ConvenientKeyStore.UserKeyStore;
import static com.softwarecraftsmen.orogeny.filing.AbsoluteDirectories.absoluteDirectories;
import static com.softwarecraftsmen.orogeny.filing.findFileFilters.AbstractFindFilesFilter.*;
import static com.softwarecraftsmen.orogeny.properties.PropertyName.EnvironmentPATH;

/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */

//TODO: This will fail on Windows systems and vice versa; parsing currently finds the default file system to interpret characters
//
@BaseDirectory("..")
@UpperCaseEnvironmentVariableOnWindows({"PATH", "CLASSPATH"})
public class Demonstration2Compiling extends BuildScript
{{
	final AbsoluteDirectory output = inBuildDirectory("outputX");
	final AbsoluteDirectory library = inBuildDirectory("library");
	final AbsoluteDirectory source = inBuildDirectory("source");

	final AbsoluteFile annotationsClassPath = library.subDirectory("IntelliJ", "7").file("annotations.jar");

	// Executable example
	task("executable").does
	(
		execute(operatingSystemAndPathDependentExecutable("java")).inWorkingDirectory(inBuildDirectory()).forUpTo(FifteenSeconds).
		withArgument("-help").
		withArguments
		(
			"-verbose", "-X"
		).
		withEnvironmentVariable("PATH", EnvironmentPATH)
	);

	// All the possible compile operations used in the module action
	final String name = "operatingSystems";
	final AbsoluteDirectories sourceDirectories = absoluteDirectories(source.subDirectory("operatingSystems"));
	final AbsolutePath classPath = annotationsClassPath;
	final AbsoluteDirectory moduleOutputDirectory = output.subDirectory(name);
	final AbsoluteDirectory generatedSourceDirectory = moduleOutputDirectory.subDirectory("generatedSource");
	final AbsoluteDirectory distributionDirectory = moduleOutputDirectory.subDirectory("distribution");
	final AbsoluteDirectory classesDirectory = moduleOutputDirectory.subDirectory("classes");
	final String jarName = name + ".jar";
	final AbsoluteFile jarFile = distributionDirectory.file(jarName);
	final AbsoluteFile sourceZipFile = moduleOutputDirectory.file(name + ".source.zip");
	final AbsolutePaths registrationPath = classPath.and(jarFile);
	final String mainClassName = "";
	task("compile example").does
	(
		makeDirectory(generatedSourceDirectory),
		compile(sourceDirectories).usingClassPath(classPath).toOutputDirectory(classesDirectory).processAnnotationsWith().generatingSourceTo(generatedSourceDirectory),
		hardLinkFiles(AllFilesExcludingHiddenFilesAndHiddenFoldersAndJavaSource.exclude(HasIntelliJFileExtension)).from(sourceDirectories.and(generatedSourceDirectory)).to(classesDirectory),
		classExists(mainClassName).in(classesDirectory).unless(mainClassName.isEmpty()),
		manifest(classesDirectory).withClassPath(classPath).withMainClass(mainClassName),
		touch(classesDirectory).where(AllFilesExcludingHiddenFilesAndHiddenFolders).withBuildDateTime(),
		makeDirectory(distributionDirectory),
		archiveAs(ZipArchive).to(jarFile).roots(classesDirectory).capturing(AllFilesExcludingHiddenFilesAndHiddenFolders),
		touch(jarFile).where(HasJarFileExtension).withBuildDateTime(),
		archiveAs(ZipArchive).to(sourceZipFile).roots(sourceDirectories.and(generatedSourceDirectory)).capturing(AllFilesExcludingHiddenFilesAndHiddenFolders),
		touch(sourceZipFile).where(HasZipFileExtension).withBuildDateTime(),
		flatHardLinkFiles(ZipOrJar).from(classPath).to(distributionDirectory),
		register(name).asPaths(registrationPath)
	);

	task("compile filing").dependsOn("compile operatingSystems").does
	(
		module("filing").compile(source.subDirectory("filing")).usingClassPath(registeredPaths("operatingSystems")).toOutputDirectory(output).withoutMainClass()
	);

	final AbsoluteFile uberJar = output.file("uberJar.jar");
	task("compile").dependsOn("compile operatingSystems").dependsOn("compile filing").dependsOn("compile commandLine").does
	(
		jarTogether(output).capturing(ZipOrJar).to(uberJar).withoutClassPath(),
		signJars(uberJar).using(key("Raph").password("password")).in(UserKeyStore.password("storepass"))
	);
}}
